package com.zhiche.lisa.bms.service.fee.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.dao.mapper.fee.FeeReceivableMapper;
import com.zhiche.lisa.bms.dao.model.cost.CostMid;
import com.zhiche.lisa.bms.dao.model.fee.FeeReceivable;
import com.zhiche.lisa.bms.dao.model.fee.FeeType;
import com.zhiche.lisa.bms.pojo.dto.fee.FeeReceivableDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspBasicDTO;
import com.zhiche.lisa.bms.service.cost.impl.CostMidServiceImpl;
import com.zhiche.lisa.bms.service.fee.FeeReceivableService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.service.utils.MdmUtil;
import com.zhiche.lisa.bms.service.utils.OmsUtil;
import com.zhiche.lisa.bms.service.utils.TmsUtil;
import com.zhiche.lisa.bms.service.utils.common.AccountBindUtil;
import com.zhiche.lisa.core.supports.BaseException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * <p>
 * 应收账款 服务实现类
 *
 * @author qichao
 * @since 2018-09-05
 */
@Service
public class FeeReceivableServiceImpl extends ServiceImpl<FeeReceivableMapper, FeeReceivable> implements FeeReceivableService {
    private static final Logger LOGGER = LoggerFactory.getLogger(FeeReceivableService.class);
    @Autowired
    private LspUtil lspUtil;
    @Autowired
    private CostMidServiceImpl costMidService;
    @Autowired
    private FeeTypeServiceImpl feeTypeService;
    @Autowired
    private OmsUtil omsUtil;
    @Autowired
    private TmsUtil tmsUtil;
    @Autowired
    private MdmUtil mdmUtil;

    /**
     * 分页查询应收账款
     *
     * @param page
     * @return
     */
    @Override
    public Page<FeeReceivable> lisaFeeReceivableLinePage(Page<FeeReceivable> page) {
        try {
            EntityWrapper<FeeReceivable> ew = buildCondition(page.getCondition());
            List<FeeReceivable> list = baseMapper.selectPage(page, ew);
            page.setRecords(list);
            return page;
        } catch (BaseException e) {
            LOGGER.error("LisaFeeReceivableServiceImpl.lisaFeeReceivableLinePage:" + e.getMessage());
            throw new BaseException("获取应收账款异常");
        } catch (Exception e) {
            LOGGER.error("LisaFeeReceivableServiceImpl.lisaFeeReceivableLinePage:" + e.getMessage());
            throw e;
        }

    }

    private EntityWrapper<FeeReceivable> buildCondition(Map<String, Object> condition) {
        EntityWrapper<FeeReceivable> ew = new EntityWrapper<>();
        ew.orderBy("id desc");
        if (!Objects.equals(condition, null)) {
            for (Map.Entry<String, Object> entry : condition.entrySet()) {
                if (Objects.nonNull(entry.getValue())) {
                    if (!StringUtils.isEmpty(String.valueOf(entry.getValue()))) {
                        if ("payerId".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("payer_id", String.valueOf(entry.getValue()));
                        }
                        if (entry.getKey().equals("contractName") && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("contract_name", String.valueOf(entry.getValue()));
                        }
                        if (entry.getKey().equals("loadStatus") && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("load_status", String.valueOf(entry.getValue()));
                        }
                        if (entry.getKey().equals("orderCode") && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            String[] str = String.valueOf(entry.getValue()).trim().replace(" ", "").split(",|\n|;");
                            ew.in("order_code", str);
                        }
                        if (entry.getKey().equals("orderDate") && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.ge("order_date", String.valueOf(entry.getValue()));
                        }
                        if (entry.getKey().equals("receiptDate") && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.le("order_date", String.valueOf(entry.getValue()));
                        }
                    }
                }
            }
        }
        ew.andNew().eq("is_delete", 0).or().isNull("is_delete");
        return ew;
    }

    /**
     * 查询列表中已有的合同名称
     *
     * @return
     */
    @Override
    public List<FeeReceivable> selectContractCode() {
        EntityWrapper<FeeReceivable> ew = new EntityWrapper();
        ew.groupBy("contract_code");
        List<FeeReceivable> list = this.selectList(ew);
        return list;
    }

    /**
     * 获取承运商名称
     *
     * @param authorization
     * @return
     */
    @Override
    public List<LspBasicDTO> queeryLspNameByLspId(String authorization) {
        EntityWrapper<FeeReceivable> ew = new EntityWrapper<>();
        ew.groupBy("payer_id");
        List<FeeReceivable> list = this.selectList(ew);
        List<Long> longList = new ArrayList<>();
        for (FeeReceivable lisaFeeReceivable : list) {
            longList.add(lisaFeeReceivable.getPayerId());
        }
        List<LspBasicDTO> listlsp = lspUtil.getLspName(longList, authorization);
        return listlsp;
    }

    /**
     * 新增应收账款
     *
     * @param lisaFeeReceivables
     * @param token
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<Long> insertFeeReceivablebms(List<FeeReceivable> lisaFeeReceivables, String token) {
        List<Long> ids = Lists.newArrayList();
        try {
            if (CollectionUtils.isEmpty(lisaFeeReceivables)) {
                throw new BaseException("请输入生成应收账款信息");
            }
            List<String> wayBillDtlIds = new ArrayList<>();
            for (int i = 0; i < lisaFeeReceivables.size(); i++) {
                wayBillDtlIds.add(lisaFeeReceivables.get(i).getWaybillDtlId());
            }
            // 将以存在的应收账款状态更新
            updateFeeReceivableExist(wayBillDtlIds);
            // 从OMS数据库获取应收账款信息
            Map<String, FeeReceivableDTO> mapOMS = omsUtil.queryFeeReceivableOms(wayBillDtlIds, token);
            // 从MDM数据库获取应收账款信息
            //Map<Long, String> mapMdm = mdmUtil.queryTransModel(mapOMS, token);
            // 获取费用信息
            Map<String, CostMid> mapCost = costMidService.queryCostMidByBillIds(wayBillDtlIds);
            // 获取费用类型信息
            Map<String, Long> mapFeeType = feeTypeService.queryFeeTypeByTypeName();
            for (FeeReceivable feeReceivable : lisaFeeReceivables) {
                String wayBillDtlId = feeReceivable.getWaybillDtlId();
                //判断运单明细ID、运单号、是否为空
                if (!StringUtils.isEmpty(wayBillDtlId) && !StringUtils.isEmpty(feeReceivable.getWaybillId())) {
                    if (Objects.nonNull(mapOMS.get(wayBillDtlId))) {
                        FeeReceivableDTO feeReceivableOMS = mapOMS.get(wayBillDtlId);
                        insertFeeReceivableByOms(feeReceivable, feeReceivableOMS);
                        //获取运输方式
                        //if (!mapMdm.isEmpty())
                        //    feeReceivable.setTransModel(mapMdm.get(feeReceivableOMS.getTransTypeId()));
                    }
                    // 获取CostMid信息
                    if (!mapCost.isEmpty() && Objects.nonNull(mapCost.get(wayBillDtlId))) {
                        insertFeeReceivableByCost(feeReceivable, mapCost.get(wayBillDtlId));
                    }
                    // 获取创建人
                    if (Objects.nonNull(feeReceivable.getTenantId())) {
                        new AccountBindUtil<FeeReceivable>().bindCreatorAndTenantId(feeReceivable, false);
                    } else {
                        new AccountBindUtil<FeeReceivable>().bindCreatorAndTenantId(feeReceivable, true);
                    }
                    // 获取费用类型信息
                    if (!mapFeeType.isEmpty() && !Objects.isNull(mapFeeType.get(feeReceivable.getTypeName()))) {
                        feeReceivable.setTypeId(mapFeeType.get(feeReceivable.getTypeName()));
                    } else {
                        //新建费用类型
                        createFeeType(feeReceivable);
                    }
                    feeReceivable.setIsDelete(0);
                    this.insert(feeReceivable);
                    ids.add(feeReceivable.getId());

                }
            }
            return ids;
        } catch (BaseException e) {
            LOGGER.error("LisaFeeReceivableServiceImpl.insertFeeReceivablebms:" + e.getMessage());
            throw new BaseException("新增应收账款异常");
        } catch (Exception e) {
            LOGGER.error("LisaFeeReceivableServiceImpl.insertFeeReceivablebms:" + e.getMessage());
            throw e;
        }
    }

    /**
     * 根据id返回sum价格结果
     *
     * @param ids
     * @return
     */
    @Override
    public BigDecimal querySumNoTenant(List<Long> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            return baseMapper.selectSumNoTenant(new EntityWrapper<FeeReceivable>().in("id", ids));
        }
        return null;
    }

    /**
     * 将Oms集成数据存入
     *
     * @param feeReceivable
     * @param feeReceivableOMS
     */
    private void insertFeeReceivableByOms(FeeReceivable feeReceivable, FeeReceivableDTO feeReceivableOMS) {
        if (Objects.nonNull(feeReceivableOMS)) {
            feeReceivable.setOrderCode(feeReceivableOMS.getOrderCode());
            feeReceivable.setOrderDtlId(feeReceivableOMS.getOrderDtlId());
            feeReceivable.setVin(feeReceivableOMS.getVin());
            feeReceivable.setOrderDate(feeReceivableOMS.getOrderDate());
            feeReceivable.setGmtCreate(feeReceivableOMS.getGmtCreate());
            feeReceivable.setNum(feeReceivableOMS.getNum());

        }
    }

    /**
     * 将CostMid集成数据存入
     *
     * @param feeReceivable
     * @param costMid
     */
    private void insertFeeReceivableByCost(FeeReceivable feeReceivable, CostMid costMid) {
        feeReceivable.setContractType(costMid.getContractType());
        feeReceivable.setContractCode(costMid.getCode());
        feeReceivable.setActualPrice(costMid.getPrice());
        feeReceivable.setKilometre(costMid.getAttribute1());
        feeReceivable.setActualAmt(costMid.getAmount());
        feeReceivable.setCostId(costMid.getId());
        feeReceivable.setTypeName(costMid.getItemName());
    }

    /**
     * 新建费用类型
     *
     * @param feeReceivable
     */
    private void createFeeType(FeeReceivable feeReceivable) {
        FeeType feeType = new FeeType();
        feeType.setTypeName(feeReceivable.getTypeName());
        feeType.setIsPayable(0);
        feeType.setIsReceivable(1);
        feeType.setTenantId(feeReceivable.getTenantId());
        feeTypeService.insert(feeType);
        feeReceivable.setTypeId(feeType.getId());
    }

    /**
     * 将以存在的应收账款状态更新
     *
     * @param wayBillDtlIds
     */
    private void updateFeeReceivableExist(List<String> wayBillDtlIds) {
        EntityWrapper<FeeReceivable> ew = new EntityWrapper<>();
        ew.in("waybill_dtl_id", wayBillDtlIds);
        ew.eq("is_delete", 0);
        List<FeeReceivable> feeReceivableList = new ArrayList<>();
        List<FeeReceivable> feeReceivables = baseMapper.selectListNoTenant(ew);
        if (!CollectionUtils.isEmpty(feeReceivables)) {
            for (FeeReceivable feeReceivableVo : feeReceivables) {
                if (!Objects.isNull(feeReceivableVo)) {
                    feeReceivableVo.setIsDelete(1);
                }
                feeReceivableList.add(feeReceivableVo);
            }
            this.updateBatchById(feeReceivableList);
        }
    }

    /**
     * 得到查询条件得到应收账款
     *
     * @param ew
     * @return
     */
    @Override
    public List<FeeReceivable> getFeeReceivableList(EntityWrapper<FeeReceivable> ew) {
        return baseMapper.selectListNoTenant(ew);
    }
}
